package io.hepu.robotize.http;

import io.hepu.robotize.enums.IStatus;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.io.Serializable;

@ApiModel(value = "返回实体对象", description = "响应HTTP请求后返回的实体对象")
public class HttpResponse<T> implements Serializable {

    @ApiModelProperty(value = "响应代码")
    private int code;

    @ApiModelProperty(value = "返回的信息")
    private String message;

    @ApiModelProperty(value = "返回的数据")
    private T data;

    public HttpResponse(IStatus status) {
        this(status.code(), status.message());
    }

    public HttpResponse(T data, IStatus status) {
        this(data, status.code(), status.message());
    }

    public HttpResponse(int code, String message) {
        this(null, code, message);
    }

    public HttpResponse(T data, int code, String message) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * Requests succeeded
     *
     * @return HttpStatus.SUCCESS whit empty data
     */
    public static <T> HttpResponse<T> success() {
        return new HttpResponse<>(IStatus.SUCCESS);
    }

    /**
     * Requests failed
     *
     * @return HttpStatus.FAILURE whit empty data
     */
    public static <T> HttpResponse<T> fail() {
        return new HttpResponse<>(IStatus.FAILURE);
    }

    /**
     * Requests succeeded
     *
     * @return HttpStatus.SUCCESS whit data
     */
    public static <T> HttpResponse<T> success(T data) {
        return new HttpResponse<>(data, IStatus.SUCCESS);
    }

    /**
     * Requests failed
     *
     * @return HttpStatus.FAILURE whit data
     */
    public static <T> HttpResponse<T> fail(T data) {
        return new HttpResponse<>(data, IStatus.FAILURE);
    }

    /**
     * Returns status code and message
     */
    public static <T> HttpResponse<T> of(int code, String message) {
        return new HttpResponse<>(code, message);
    }

    /**
     * Returns status code and message
     */
    public static <T> HttpResponse<T> of(IStatus status) {
        return new HttpResponse<>(status);
    }

    /**
     * Returns status code and message whith data
     */
    public static <T> HttpResponse<T> of(IStatus status, T data) {
        return new HttpResponse<>(data, status);
    }

    /**
     * Returns IStatus.NO_CONTENT code and empty data
     *
     * @param data entity payload
     * @param <T>  entity class type
     */
    public static <T> HttpResponse<T> empty(T data) {
        return HttpResponse.of(IStatus.NO_CONTENT, data);
    }

    /**
     * Returns on conditions
     */
    public static <T> HttpResponse<T> when(boolean expected, T data) {
        return expected ? success(data) : fail(data);
    }

    // ------------------
    //  Getter & Setter
    // ------------------
    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public T getData() {
        return data;
    }

    public HttpResponse<T> code(int code) {
        this.code = code;
        return this;
    }

    public HttpResponse<T> message(String message) {
        this.message = message;
        return this;
    }

    public HttpResponse<T> data(T data) {
        this.data = data;
        return this;
    }

    @Override
    public String toString() {
        return "HttpResponse [code=" + code + ", message=" + message + ", data=" + data + "]";
    }

}
